package com.cn.common.core;

import com.cn.common.model.Result;
import com.cn.common.utils.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.List;

@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    public GlobalExceptionHandler() {
    }

    @ExceptionHandler({ServiceException.class})
    public Result businessException(ServiceException e) {
        log.error(e.getMessage(), e);
        return Result.error(e.getCode(), e.getMessage());
    }


    @ExceptionHandler({HttpMessageNotReadableException.class})
    public Result requestNotReadable(HttpMessageNotReadableException e) {
        log.error(e.getMessage(), e);
        return Result.error(400, e.getMessage());
    }

    @ExceptionHandler({MissingServletRequestParameterException.class})
    public Result requestMissingServletRequest(MissingServletRequestParameterException e) {
        log.error(e.getMessage(), e);
        return Result.error(400, e.getMessage());
    }

    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public Result request405(HttpRequestMethodNotSupportedException e) {
        log.error(e.getMessage(), e);
        return Result.error(405, "不支持请求方法");
    }

    @ExceptionHandler({SocketTimeoutException.class})
    public Result SocketTimeoutException(SocketTimeoutException e) {
        log.error(e.getMessage(), e);
        return Result.error(501, "连接超时,请检查网络环境或重试");
    }

    @ExceptionHandler({IOException.class})
    public Result iOExceptionHandler(IOException ex) {
        log.error(ex.getMessage(), ex);
        return Result.error(400, ex.getMessage());
    }

    @ExceptionHandler({NoHandlerFoundException.class})
    public Result handlerNoFoundException(Exception e) {
        log.error(e.getMessage(), e);
        return Result.error(404, "路径不存在，请检查路径是否正确");
    }

    @ExceptionHandler({MethodArgumentNotValidException.class})
    public Result handleIllegalParamException(MethodArgumentNotValidException e) {
        log.error(e.getMessage(), e);
        String message = "参数不合法";
        List<FieldError> errors = e.getBindingResult().getFieldErrors();
        if (errors.size() > 0) {
            message = ((FieldError)errors.get(0)).getDefaultMessage();
        }

        return Result.error(400, message);
    }

    @ExceptionHandler({RuntimeException.class})
    public Result handle(Exception e) {
        log.error(e.getMessage(), e);
        return Result.error("服务异常" + e.getMessage());
    }

}